import java.io.IOException;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

/**
 * This class handles the schema file in the EB-forms system.
 * It can generate the tree, and lookup dictionary entry names.
 * @author AXXXE
 *
 */
public class SchemafileHandler {

	//The schema on which the operations are done.
	private Document schemaDoc;
	
	/**
	 * The constructor for SchemafileHandler. Constructs a java readable
	 * node to read.
	 * @param filename the filename for the schema.
	 * @throws IOException
	 * @throws SAXException
	 * @throws ParserConfigurationException
	 */
	public SchemafileHandler(String filename) throws IOException, SAXException, ParserConfigurationException{
		schemaDoc = XMLHandler.readFile(filename);	
	}
	
	/**
 	* gets the Definition value of the element item.   
 	* @param item the element from which the Definition value has to be returned
 	* @return the Definition value of the item, null if not found
 	**/
	public String getDefinition(ListItem item){
		if (item.getNode() == null)return null;
		Node n = XMLHandler.getChildNodeByName(item.getNode(), "xsd:annotation");
		if (n == null)return null;
		n = XMLHandler.getChildNodeByName(n,"xsd:documentation");
		if (n == null)return null;
		n = XMLHandler.getChildNodeByName(n,"ccts:Definition");
		if (n == null) return null;
		try {
			return n.getTextContent();
		}
		catch (DOMException e)
		{
			return null;
		}
	}
	
	/**
 	* gets the DictionaryEntryName value of the element item.   
 	* @param item the element from which the DictionaryEntryName value has to be returned
 	* @return the DictionaryEntryName value of the item
 	**/
	public String getDictionaryEntryName(ListItem item){
		if (item.getNode() == null)return null;
		Node n = XMLHandler.getChildNodeByName(item.getNode(), "xsd:annotation");
		if (n == null)return null;
		n = XMLHandler.getChildNodeByName(n,"xsd:documentation");
		if (n == null)return null;
		n = XMLHandler.getChildNodeByName(n,"ccts:DictionaryEntryName");
		if (n == null) return null;
		try {
			return n.getTextContent();
		}
		catch (DOMException e)
		{
			return null;
		}				
	}
	
	/**
 	* Generates a root node containing the elements from the schema file.
	* @return DefaultMutableTreeNode containing ListItems
 	**/
	public DefaultMutableTreeNode getTree() {
		DefaultMutableTreeNode root = new DefaultMutableTreeNode(new ListItem("Schema",null,true));		
		Node n = schemaDoc.getDocumentElement();						
		root = getSubTree(root, n);
		return root;
	}
	/**
 	* Recursively creates a tree based on <tt>n</tt> using <tt>parentNode</tt> 
 	* as a root node.
 	* @param parentNode 
 	* @param n 
	* @return DefaultMutableTreeNode containing ListItems
 	**/
	private DefaultMutableTreeNode getSubTree(DefaultMutableTreeNode parentNode, Node n) {
		
		n = n.getFirstChild();
		while (n != null) {
			if (n.getNodeName() == "xsd:sequence") {
				  n = n.getFirstChild();
			}				  
			if (n.getNodeName() == "xsd:element") {
				String value = n.getAttributes().getNamedItem("name").getNodeValue();
				ListItem item = new ListItem(value, n);
				DefaultMutableTreeNode newnode = new DefaultMutableTreeNode(item);
				parentNode.add(newnode);
			}
			else if (n.getNodeName() == "xsd:complexType"){
				String value = n.getAttributes().getNamedItem("name").getNodeValue();
				DefaultMutableTreeNode newnode = new DefaultMutableTreeNode(new ListItem(value, n));
				newnode = getSubTree(newnode, n);
				parentNode.add(newnode);					
			}
			n = n.getNextSibling();  
		  }
		return parentNode;
	}
	
}
